package com.wenlin.myproduction.widget;

import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.content.Context;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.OvershootInterpolator;
import android.widget.ImageView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.wenlin.myproduction.R;
import com.wenlin.myproduction.util.Checker;
import com.wenlin.myproduction.util.ToastUtils;

import java.io.File;

/**
 * 可以翻转的卡片控件，20210222 增加镜像图片
 */
public class FrontAndBackView {
    private static final int MIN_TIMES = 2;//最少转几下
    private static final int MAX_TIME_MILLIS = 20 * 1000;//最多转多少毫秒
    private static final int ANIM_DUR = 1000;//动画时长
    private ImageView faceView, backView;//卡片的正面和反面
    private boolean isStart = false;//是否已经开始翻转了
    private ObjectAnimator oaToFace, oaToBack;
    private Context context;//上下文
    private boolean getRes;//是否获取到奖品图片到本地
    private boolean done;//是否已经完成并显示最终的奖品图片
    private File fileGift;//奖品图片文件
    private int times;//转几下
    private Listener listener;//翻卡动画执行完成之后的回调

    public FrontAndBackView(Context context, ImageView frontView, ImageView backView) {
        this.context = context;
        this.faceView = frontView;
        backView.setScaleX(-1);//显示镜像图片
        this.backView = backView;
        this.faceView.setVisibility(View.VISIBLE);
        this.backView.setVisibility(View.GONE);
        setCameraDistance();
        initAnim();
    }

    /**
     * 初始化动画
     */
    private void initAnim() {
        //转向前面的动画
        oaToFace = new ObjectAnimator();
        oaToFace.setFloatValues(-90f, 0f);
        oaToFace.setDuration(ANIM_DUR / 2);
        oaToFace.setPropertyName("rotationY");
        oaToFace.setInterpolator(new DecelerateInterpolator());
        //转向后面的动画
        oaToBack = new ObjectAnimator();
        oaToBack.setFloatValues(0f, 90f);
        oaToBack.setDuration(ANIM_DUR / 2);
        oaToBack.setPropertyName("rotationY");
        oaToBack.setInterpolator(new DecelerateInterpolator());
        //转向后面之后，切换图片，再转向前面
        oaToBack.addUpdateListener(animation -> {
            if ((float) animation.getAnimatedValue() == 90f) {
                backView.setVisibility(View.VISIBLE);
                faceView.setVisibility(View.GONE);
                oaToFace.start();
            }
        });
        //转向前面之后，对调前后两张图片的位置，即原来的前图变成后图，后图变成前图
        oaToFace.addUpdateListener(animation -> {
            if ((float) animation.getAnimatedValue() == 0f) {
                //交换正反面
                ImageView view = faceView;
                faceView = backView;
                backView = view;
                animStart();
            }
        });
    }

    /**
     * 设置动画执行完之后的监听
     *
     * @param listener 监听
     */
    public void setListener(Listener listener) {
        this.listener = listener;
    }

    /**
     * 执行动画
     *
     * @param url 最新的奖品的图片地址
     */
    public void toggle(String url) {
        if (isStart) return; //防止多次点击
        isStart = true;
        times = 0;
        done = false;
        getRes = false;
        downLoad(url);
        animStart();
    }

    /**
     * 开始翻转动画
     */
    private void animStart() {
        //如果已经完成了，则走回调流程
        if (done) {
            isStart = false;
            if (listener != null) listener.animDone();
            return;
        }
        //根据是否是最后一次翻转来设置动画的时长和反面图片
        if (getRes && times++ > MIN_TIMES || times * ANIM_DUR >= MAX_TIME_MILLIS) {//如果获取到资源且至少转了2下，或者转20秒仍然没下好资源，就直接走停止转动的流程
            if (Checker.notNull(fileGift)) {
                backView.setScaleX(1);
                Glide.with(context)
                        .load(fileGift)
                        .placeholder(R.mipmap.ic_loading_800_1000)
                        .error(R.mipmap.ic_image_error)
                        .into(backView);
            } else {
                ToastUtils.getInstance().showInfo("奖品图片加载超时");
            }
            oaToFace.setInterpolator(new OvershootInterpolator());
            oaToFace.setDuration(ANIM_DUR / 2);
            oaToBack.setDuration(ANIM_DUR / 2);
            done = true;
        } else {
            oaToFace.setDuration(ANIM_DUR / 4);
            oaToBack.setDuration(ANIM_DUR / 4);
        }
        //设置动画并开始动画，这里的动画因为在初始化方法中加了监听，所以是相互调用的关系，根据上方的判断无论如何都会停止的。不会出现死循环
        oaToFace.setTarget(backView);
        oaToBack.setTarget(faceView);
        oaToBack.start();
    }

    /**
     * 下载图片
     *
     * @param url 图片地址
     */
    private void downLoad(String url) {
        Glide.with(context).downloadOnly().load(url).into(new SimpleTarget<File>() {
            @Override
            public void onResourceReady(@NonNull File resource, @Nullable Transition<? super File> transition) {
                fileGift = resource;
                getRes = true;
            }
        });
    }

    /**
     * rotationY属性变换时需要调整相机距离，否则会影响用户体验
     */
    private void setCameraDistance() {
        int distance = 16000;
        float scale = context.getResources().getDisplayMetrics().density * distance;
        faceView.setCameraDistance(scale);
        backView.setCameraDistance(scale);
    }

    /**
     * 监听回调的接口
     */
    public interface Listener {
        void animDone();
    }

    /**
     * 线性值插值器
     */
    static class LinearAnim implements TimeInterpolator {

        @Override
        public float getInterpolation(float input) {
            return input;
        }
    }
}